package com.whxd.framework.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * <i>Copyright(c) 2008-2010 the original author or authors<br>
 * 
 * @version 1.0 (2008-7-3)
 * 
 * @author <a href="mailto:34205037@qq.com">王健</a>
 */
public final class DateUtil {

	public static final String YEAR_MONTH_DAY_SEPARATOR = "-";

	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 获得当前月份的下一月份.
	 * 
	 * @return 月份的整数值.
	 */
	public static int nextMonth() {
		return nextMonth(1);
	}

	/**
	 * 获得当前月份向下滚动后的月份值.
	 * 
	 * @param value
	 *            滚动的数量值
	 * @return 月份的整数值.
	 */
	public static int nextMonth(int value) {
		return nextMonth(GregorianCalendar.getInstance().get(Calendar.MONTH) + 1, value);
	}

	/**
	 * 获得月份向下滚动后的月份值.
	 * 
	 * @param month
	 *            初始的月份值(1-12)
	 * @param value
	 *            滚动的数量值
	 * @return 月份的整数值.
	 */
	public static int nextMonth(int month, int value) {
		return (month + (value < 0 ? (value % 12 + 12) : value) - 1) % 12 + 1;
	}

	/**
	 * 获得当前月份的上一月份.
	 * 
	 * @return 月份的整数值.
	 */
	public static int previousMonth() {
		return nextMonth(-1);
	}

	/**
	 * 获得当前月份向上滚动后的月份值.
	 * 
	 * @param value
	 *            滚动的数量值
	 * @return 月份的整数值.
	 */
	public static int previousMonth(int value) {
		return nextMonth(value * -1);
	}

	/**
	 * 获得月份向上滚动后的月份值.
	 * 
	 * @param month
	 *            初始的月份值(1-12)
	 * @param value
	 *            滚动的数量值
	 * @return 月份的整数值.
	 */
	public static int previousMonth(int month, int value) {
		return nextMonth(month, value * -1);
	}

	/**
	 * 将一个整数值的月份补0(如果需要),此方法不进行月份有效性的验证.
	 * 
	 * @param month
	 *            月份值(1-12)
	 * @return 月份被补位后的字符串形式.
	 */
	public static String complementMonth(int month) {
		return (month < 10 ? "0" : "") + month;
	}

	/**
	 * 验证一个日期(年月日)字符串是否合法.
	 * 
	 * @param date
	 *            日期(年月日)字符串
	 * @return 验证后的boolean值,合法返回true,非法返回false.
	 */
	public static boolean validate(String date) {
		return validate(date, DateUtil.YEAR_MONTH_DAY_SEPARATOR);
	}

	/**
	 * 验证一个日期(年月日)字符串是否合法.
	 * 
	 * @param date
	 *            日期(年月日)字符串
	 * @param separator
	 *            日期(年月日)的分隔符
	 * @return 验证后的boolean值,合法返回true,非法返回false.
	 */
	public static boolean validate(String date, String separator) {
		Pattern p = Pattern.compile(String.format("^(\\d{2,4}%1$s\\d{1,2}%1$s\\d{1,2})$", separator));
		Matcher m = p.matcher(date);
		if (!m.matches()) {
			return false;
		}
		DateFormat format = new SimpleDateFormat(String.format("yyyy%1$sMM%1$sdd", separator));
		format.setLenient(false);
		try {
			format.parse(date);
		} catch (ParseException e) {
			return false;
		}
		return true;
	}

	/**
	 * 格式化日期字符串.
	 * 
	 * @param date
	 *            日期字符串
	 * @param oldFormat
	 *            日期字符串原来的格式
	 * @return 格式化后的日期字符串(使用DateUtil.DATETIME_FORMAT作为新的日期格式).
	 */
	public static String format(String date, String oldFormat) throws ParseException {
		return format(date, oldFormat, DateUtil.DATETIME_FORMAT);
	}

	/**
	 * 格式化日期字符串.
	 * 
	 * @param date
	 *            日期字符串
	 * @param oldFormat
	 *            日期字符串原来的格式
	 * @param newFormat
	 *            日期字符串新的格式
	 * @return 格式化后的日期字符串.
	 */
	public static String format(String date, String oldFormat, String newFormat) throws ParseException {
		DateFormat old = new SimpleDateFormat(oldFormat);
		old.setLenient(false);
		return new SimpleDateFormat(newFormat).format(old.parse(date));
	}

	/**
	 * 获得当前系统日期.
	 * 
	 * @return 当前系统时间的字符串形式(使用DateUtil.DATETIME_FORMAT作为日期格式).
	 */
	public static String currentDatetime() {
		return currentDatetime(DateUtil.DATETIME_FORMAT);
	}

	/**
	 * 获得当前系统日期.
	 * 
	 * @param format
	 *            日期格式
	 * @return 当前系统时间的字符串形式.
	 */
	public static String currentDatetime(String format) {
		return new SimpleDateFormat(format).format(new Date());
	}

	/**
	 * 获得需要日期的字符串形式.
	 * 
	 * @param format
	 *            日期格式
	 * @return 当前系统时间的字符串形式.
	 */
	public static String datetimeStr(String format, Date date) {
		return new SimpleDateFormat(format).format(date);
	}

	public static void main(String[] args) {
		try {
			System.out.println(DateUtil.format("2008/1/91 08:9:21:100", "yyyy/M/d hh:m:ss:SSS", "yy,M,dd h:mm:s:S"));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.out.println(DateUtil.currentDatetime());
	}

	/**
	 * 日期加多少天
	 * 
	 * @author 王泽鑫
	 * @since 2013-8-24
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date addDay(Date date, Integer day) {
		if (date != null) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(Calendar.DATE, day);
			return cal.getTime();
		}
		return null;
	}

	/**
	 * 日期减多少天
	 * 
	 * @author 王泽鑫
	 * @since 2013-8-24
	 * @param date
	 * @param day
	 * @return
	 */
	public static Date minusDay(Date date, Integer day) {
		if (date != null) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(Calendar.DATE, -day);
			return cal.getTime();
		}
		return null;
	}

	/**
	 * 日期加上多少个月
	 * 
	 * @author 张世鹏
	 * @since 2013-9-26
	 * @param date
	 * @param month
	 * @return
	 */
	public static Date addMonth(Date date, Integer month) {
		if (date != null) {
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			cal.add(Calendar.MONTH, month);
			return cal.getTime();
		}
		return null;
	}

	/**
	 * 比较两个时间大小(忽略日期，只比较时间)
	 * 
	 * @author 王泽鑫
	 * @since 2013-9-5
	 * @param time1
	 * @param time2
	 * @return
	 * @throws ParseException
	 */
	public static int compareTime(Date time1, Date time2) throws ParseException {
		SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
		String time1str = sdfTime.format(time1);
		String time2str = sdfTime.format(time2);
		Date time1Date = sdfTime.parse(time1str);
		Date time2Date = sdfTime.parse(time2str);
		return time1Date.compareTo(time2Date);
	}

	/**
	 * 此方法比较 时间cdate 是否在 time1 和time2之间(带日期比较)
	 * 
	 * @author 王泽鑫
	 * @since 2013-9-5
	 * @param cdate
	 * @param time1
	 * @param time2
	 * @return
	 * @throws ParseException
	 */
	public static Boolean isBetween(Date cdate, Date time1, Date time2) {
		if (cdate.compareTo(time1) >= 0 && time2.compareTo(cdate) >= 0) {
			return true;
		}
		return false;
	}

	/**
	 * 把传入的日期时间中的年月日转换成当前的年月日
	 * 
	 * @author 王泽鑫
	 * @since 2013-9-16
	 * @param time
	 * @return
	 */
	public static Date getDate(Date time) {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String timeStr1 = sdf.format(time);
		String timeStr2 = sdf.format(date);
		String newDate1 = timeStr2.split(" ")[0] + " " + timeStr1.split(" ")[1];
		try {
			Date dates = sdf.parse(newDate1);
			return dates;
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 转换系统日期时间中的时分秒
	 * 
	 * @author 张世鹏
	 * @since 2013-9-27
	 * @return
	 */
	public static Date getCurrentDate() {
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
		String timeStr2 = sdf.format(date);
		try {
			Date dates = sdf.parse(timeStr2);
			return dates;
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 比较两个日期是否在同一天
	 * 
	 * @author 王泽鑫
	 * @since 2013-10-7
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static Boolean compareDate(Date date1, Date date2) {
		Boolean isBoolean = false;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		String date1Str = sdf.format(date1);
		String date2Str = sdf.format(date2);
		try {
			if (sdf.parse(date1Str).compareTo(sdf.parse(date2Str)) == 0) {
				isBoolean = true;
			}
		} catch (ParseException e) {
			e.printStackTrace();
			e.getMessage();
		}
		return isBoolean;
	}

	/**
	 * 比较end - begin 的时间差是否> hours个小时
	 * 
	 * @author 王泽鑫
	 * @since 2013-11-25
	 * @param end
	 *            结束时间
	 * @param begin
	 *            当前开始时间
	 * @param hours
	 *            小时数
	 * @return
	 * @throws ParseException
	 */
	public static Boolean isEarlyThanX(Date end, Date begin, Integer hours) throws ParseException {
		SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String endStr = dfs.format(end);
		Date endDate = dfs.parse(endStr);
		String beginStr = dfs.format(begin);
		Date beginDate = dfs.parse(beginStr);
		long between = (endDate.getTime() - beginDate.getTime()) / 1000;// 除以1000是为了转换成秒
		Integer hour = Integer.valueOf((int) between % (24 * 3600) / 3600);
		if (hour > hours) {
			return true;
		}
		return false;
	}
}